
package com.kweative.model.data;

import com.kweative.model.Schema;
import com.kweative.model.Table;
import com.kweative.model.exception.StructureException;
import com.kweative.model.column.Column;
import com.kweative.model.column.ColumnExtra;
import com.kweative.model.query.QueryUtil;
import com.mysql.jdbc.Driver;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 *
 * @author henrik
 */
abstract public class DataProvider {
    private static DataProvider instance;

    public static DataProvider instance() {
        return instance;
    }
    public static void setProvider(DataProvider provider) throws SQLException {
        instance = provider;
        instance.connect();
    }
    public static Connection connection() {
        return instance().connection;
    }

    private Driver jdbcDriver;
    private Connection connection;
    protected Properties properties = new Properties();
    private String username;
    private String password;
    private String host;
    private int port;

    public DataProvider(Driver jdbcDriver,String username, String password, String host, int port) {
        this.jdbcDriver = jdbcDriver;
        this.username = username;
        this.password = password;
        this.host = host;
        this.port = port;
    }
    public void connect() throws SQLException {
        if (connection != null && !connection.isClosed()) return;
        connection = jdbcDriver.connect(getConnectionString(),properties);
    }

    public void disconnect() throws SQLException {
        connection.close();
        connection = null;
    }

    public Connection getConnection() {
        return connection;
    }

    public String getHost() {
        return host;
    }

    public static DataProvider getInstance() {
        return instance;
    }

    public Driver getJdbcDriver() {
        return jdbcDriver;
    }

    public String getPassword() {
        return password;
    }

    public int getPort() {
        return port;
    }

    public String getUsername() {
        return username;
    }
    public String serializeColumn(Column f) {
        StringBuilder sb = new StringBuilder();
		sb.append(String.format("`%s` %s ",f.getName(),f.getSQLDataType().toString()));
		if (f.getSQLTypeParms() != null) {
			sb.append(String.format("(%s) ",f.getSQLTypeParms()));
		}
        if (f.getSQLAttribute() != null)
            sb.append(f.getSQLAttribute().toString());
		if (f.isSQLNotNull()) {
			sb.append(String.format(" NOT NULL ",QueryUtil.formatValue(f,f.getSQLDefault())));
		}
		if (f.getSQLDefault() != null) {
			sb.append(String.format(" DEFAULT %s ",QueryUtil.formatValue(f,f.getSQLDefault())));
		}
        if (f.getSQLExtra() != null)
            sb.append(f.getSQLExtra().toString());

        return sb.toString();
    }
    public String serializeSchema(Schema s) throws StructureException {
        StringBuilder sb = new StringBuilder();
        for(Table t:s.getTables()) {
            sb.append(serializeTable(t));
        }

        return sb.toString();
    }
    
    abstract public String serializeTable(Table t) throws StructureException;

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        disconnect();
    }



    abstract public String getConnectionString();
}
